package com.beiding.businessplatform.base.impl;

import com.beiding.businessplatform.base.DaoBase;
import com.beiding.businessplatform.base.ServiceBase;
import com.beiding.businessplatform.data.Be;
import com.beiding.businessplatform.data.Vm;
import com.beiding.businessplatform.data.VmInvoker;
import com.beiding.businessplatform.ql.QlUtils;
import com.beiding.businessplatform.ql.QueryBuilder;
import com.beiding.businessplatform.ql.SelectionBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ServiceBaseImpl<VmT extends Vm, BeT extends Be> implements ServiceBase<VmT> {

    private DaoBase<BeT> dao;

    private Class<VmT> vmClass;

    public void setDao(DaoBase<BeT> dao) {
        this.dao = dao;
    }

    public void setVmClass(Class<VmT> vmClass) {
        this.vmClass = vmClass;
    }

    @Override
    public VmT findOne(String ql, Map<String, Object> holderData) {
        BeT be = dao.findOne(ql, holderData);
        if (be == null) {
            return null;
        }

        VmT r = create();
        VmInvoker.be(r, be);
        return r;
    }

    @Override
    public VmT create() {
        try {
            //反射创建对象
            return vmClass.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public VmT retrieve(String id) {
        BeT be = dao.getOne(id);
        VmT a = create();
        VmInvoker.be(a, be);
        VmInvoker.mode(a, 1);
        return a;
    }

    @Override
    public void save(VmT a) {
        int mode = VmInvoker.getMode(a);
        BeT be;
        if (mode == 0) {
            be = dao.getOne(a.getId());
            if (be == null) {
                be = (BeT) VmInvoker.be(a);
                VmInvoker.update(a);
            } else {
                VmInvoker.be(a, be);
            }
        } else {
            be = (BeT) VmInvoker.be(a);
            VmInvoker.update(a);
        }
        dao.save(be);
        //保存成功内存和数据库应该是一致的
        VmInvoker.mode(a, 1);
    }

    @Override
    public VmT findOne(SelectionBuilder selectionBuilder, QueryBuilder queryBuilder) {
        QlUtils.Ql ql = QlUtils.makeQl(selectionBuilder, queryBuilder);
        return findOne(ql.getQl(), ql.getParams());
    }

    @Override
    public List<VmT> findList(String ql, Map<String, Object> holderData) {
        List<BeT> list = dao.findList(ql, holderData);
        List<VmT> r = new ArrayList<>();
        for (BeT be : list) {
            VmT a = create();
            VmInvoker.be(a, be);
            r.add(a);
        }
        return r;
    }

    @Override
    public List<VmT> findList(SelectionBuilder selectionBuilder, QueryBuilder queryBuilder) {
        QlUtils.Ql ql = QlUtils.makeQl(selectionBuilder, queryBuilder);
        return findList(ql.getQl(), ql.getParams());
    }

    public List<Map<String, Object>> queryList(String ql, Map<String, Object> holderData) {
        return dao.queryList(ql, holderData);
    }

    public Map<String, Object> queryOne(String ql, Map<String, Object> holderData) {
        return dao.queryOne(ql, holderData);
    }


}
